<template>
  <div>
    <a-alert
      message="监测服务将于每日对启用状态的网站证书进行检测，并进行预警通知。"
      type="info"
      show-icon
      style="margin-bottom: 18px"
    />
    <div class="table-page-search-wrapper">
      <a-row type="flex" justify="space-between" align="middle">
        <a-col :span="16">
          <a-form layout="inline" :model="listQuery">
            <a-form-item label="搜索项">
              <a-input v-model:value="listQuery.title" placeholder="输入标题/监控域名搜索..." />
            </a-form-item>
            <a-form-item>
              <a-button type="primary" @click="searchSubmit"> 搜索 </a-button>
            </a-form-item>
            <a-form-item>
              <a-button
                v-permission="{ action: 'del_server_batch' }"
                type="primary"
                danger
                :disabled="selectedRowKeys.length === 0"
                @click="deleteSelect"
              >
                <template #icon>
                  <DeleteOutlined />
                </template>
                删除所选
              </a-button>
            </a-form-item>
          </a-form>
        </a-col>
        <a-col :span="8">
          <div style="margin-right: 0px; float: right; display: flex; align-item: center">
            <a-tooltip placement="top">
              <template #title>
                <span>刷新列表</span>
              </template>
              <a-button @click="reloadList">
                <template #icon>
                  <SyncOutlined />
                </template>
              </a-button>
            </a-tooltip>
            <a-button
              v-permission="{ action: 'ssl_monitor_add' }"
              type="primary"
              style="margin-left: 12px"
              @click="addNewData"
            >
              <template #icon>
                <PlusOutlined />
              </template>
              新增监控配置
            </a-button>
          </div>
        </a-col>
      </a-row>
    </div>
    <a-table
      :columns="columns"
      :rowKey="(record) => record._id"
      :dataSource="dataList.data"
      :loading="loading"
      :pagination="pagination"
      :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
      @change="handleTableChange"
    >
      <template #status="{ text: record }">
        <a-tag v-if="record == 1" color="green">启用</a-tag>
        <a-tag v-if="record == 0" color="red">关闭</a-tag>
      </template>
      <template #domain_expire="{ text: record }">
        <span>起始: {{ record.start_date }}</span
        ><br />
        <span>截止: {{ record.expire_time }}</span>
      </template>
      <template #is_expire="{ text: record }">
        <a-tag v-if="record.is_expire == 1" color="green">有效</a-tag>
        <a-tooltip v-else-if="record.is_expire == -1" placement="top">
          <template #title>
            <span>{{ record.error }}</span>
          </template>
          <a-tag color="red">无效</a-tag>
        </a-tooltip>
        <a-tooltip v-else-if="record.is_expire == 2" placement="top">
          <template #title>
            <span>将于14天内过期</span>
          </template>
          <a-tag color="pink">临期</a-tag>
        </a-tooltip>
        <a-tag v-else>未检测</a-tag>
      </template>
      <template #action="{ text: record }">
        <a v-permission="{ action: 'ssl_monitor_add' }" @click="ssl_monitor_edit(record)">
          <EditOutlined /> 编辑
        </a>
        <a-divider v-permission="{ action: 'ssl_monitor_log' }" type="vertical" />
        <a v-permission="{ action: 'ssl_monitor_log' }" @click="ssl_monitor_log(record)"> 日志 </a>
        <a-divider v-permission="{ action: 'ssl_monitor_view' }" type="vertical" />
        <a v-permission="{ action: 'ssl_monitor_view' }" @click="ssl_monitor_view(record)">
          证书
        </a>
        <a-divider v-permission="{ action: 'ssl_monitor_ext' }" type="vertical" />
        <a-dropdown>
          <a v-permission="{ action: 'ssl_monitor_ext' }" class="ant-dropdown-link">
            更多
            <DownOutlined />
          </a>
          <template #overlay>
            <a-menu>
              <a-menu-item v-permission="{ action: 'ssl_monitor_copy' }">
                <a @click="ssl_monitor_copy(record)"> <CopyOutlined /> 复制 </a>
              </a-menu-item>
              <a-menu-item v-permission="{ action: 'ssl_monitor_del' }" style="color: red">
                <a @click="ssl_monitor_delete(record)"> <DeleteOutlined /> 删除 </a>
              </a-menu-item>
            </a-menu>
          </template>
        </a-dropdown>
      </template>
    </a-table>
    <a-drawer
      width="50%"
      :title="drawerTitle"
      placement="right"
      :open="drawerShow"
      @close="
        () => {
          drawerShow = false
        }
      "
    >
      <template #extra>
        <a-button
          style="margin-right: 8px"
          @click="
            () => {
              drawerShow = false
            }
          "
          >取消</a-button
        >
        <a-button type="primary" @click="addServer">提交</a-button>
      </template>
      <a-form
        ref="formRef"
        :model="FormState"
        :rules="FormRule"
        :labelCol="labelCol"
        :wrapperCol="wrapperCol"
      >
        <a-form-item label="标题" has-feedback required name="title">
          <a-input v-model:value="FormState.title" placeholder="请输入标题" />
        </a-form-item>
        <a-form-item label="通知标题预览">
          【SSL证书监控提醒】- {{ FormState.title || '标题' }}
        </a-form-item>
        <a-form-item label="监控域名" has-feedback required name="domain">
          <a-input
            v-model:value="FormState.domain"
            placeholder="请输入完整监控域名，如:www.21ds.cn或21ds.cn"
          />
        </a-form-item>
        <a-form-item label="监控通知" has-feedback required name="ps_id">
          <a-select v-model:value="FormState.ps_id" placeholder="请选择通知推送配置">
            <a-select-option v-for="d in allPush" :key="d._id" :value="d._id">
              {{ d.title }}
            </a-select-option>
            <template #notFoundContent>
              <a-empty
                image="https://img.alicdn.com/imgextra/i3/573804794/O1CN01IO097G1lHhdtoisyG_!!573804794.png"
                :image-style="{
                  height: '90px'
                }"
              >
                <template #description>
                  <view style="color: rgba(0, 0, 0, 0.88); padding-top: 20px">
                    暂无可选项，请先
                    <router-link :to="{ name: 'pushServer' }" target="_blank">添加</router-link>
                  </view>
                </template>
              </a-empty>
            </template>
          </a-select>
        </a-form-item>
        <a-form-item label="监控状态" has-feedback required name="status">
          <a-radio-group v-model:value="FormState.status">
            <a-radio :key="1" :value="1">启用</a-radio>
            <a-radio :key="0" :value="0">关闭</a-radio>
          </a-radio-group>
        </a-form-item>
      </a-form>
    </a-drawer>
    <a-modal
      v-model:open="logVisible"
      title="监测日志(日志记录仅保留7天)"
      :footer="null"
      style="width: 700px"
    >
      <a-table
        :columns="columns2"
        :rowKey="(record) => record._id"
        :dataSource="dataListLog.data"
        :loading="loading2"
        :pagination="pagination2"
        @change="handleTableChange2"
      >
        <template #status="{ text: record }">
          <a-tag v-if="record == 1" color="blue">成功</a-tag>
          <a-tag v-if="record == 0" color="red">失败</a-tag>
        </template>
      </a-table>
    </a-modal>
    <a-modal v-model:open="viewVisible" title="证书信息" :footer="null">
      <p>域名：{{ single.domain }}</p>
      <p>证书版本号：{{ single.version }}</p>
      <p>证书序列号：{{ single.serial_number }}</p>
      <p>颁发机构：{{ single.issuer.CN }}</p>
      <p>起始时间：{{ single.start_date }}</p>
      <p>截止时间：{{ single.expire_time }}</p>
    </a-modal>
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive, toRefs, onMounted, ref } from 'vue'
import {
  Row,
  Col,
  Modal,
  Divider,
  Image,
  message,
  Drawer,
  Switch,
  InputPassword,
  InputNumber,
  Tabs,
  TabPane
} from 'ant-design-vue'
import {
  SyncOutlined,
  PlusOutlined,
  EditOutlined,
  DeleteOutlined,
  DownOutlined,
  CopyOutlined,
  QuestionCircleOutlined
} from '@ant-design/icons-vue'
import { delServerItem, getSSLList, editSslInfo, getLog, delServerBatch } from '@/api/monitor'
import { randomString, inArray } from '@/utils/common'
import { useRouter } from 'vue-router'
import { requestFailed, requestSuccess } from '@/utils/feedback'
import { getAllServerList as getPushServerList } from '@/api/push'

export default defineComponent({
  name: 'AdsList',
  components: {
    SyncOutlined,
    PlusOutlined,
    DownOutlined,
    CopyOutlined,
    EditOutlined,
    QuestionCircleOutlined,
    DeleteOutlined,
    [Tabs.name]: Tabs,
    [TabPane.name]: TabPane,
    [Modal.name]: Modal,
    [Row.name]: Row,
    [Drawer.name]: Drawer,
    [Switch.name]: Switch,
    [InputPassword.name]: InputPassword,
    [InputNumber.name]: InputNumber,
    [Col.name]: Col,
    [Image.name]: Image,
    [Divider.name]: Divider
  },
  setup() {
    const formRef = ref()
    const router = useRouter()
    const state = reactive<any>({
      loading: true,
      loading2: true,
      drawerShow: false,
      logVisible: false,
      viewVisible: false,
      modalVisible: false,
      testEmail: '',
      drawerTitle: '监控配置详情',
      activeKey: 'tab1',
      testServer: {
        _id: ''
      },
      single: {
        _id: ''
      },
      dataList: [],
      selectedRowKeys: [],
      selectedKeysPage: {},
      allPush: [],
      dataListLog: [],
      listQuery: {
        pageNo: 1,
        pageSize: 15,
        title: ''
      },
      listQuery2: {
        pageNo: 1,
        pageSize: 15,
        ml_id: ''
      },
      labelCol: {
        xs: { span: 24 },
        sm: { span: 3 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 20 }
      },
      pagination: {
        pageSizeOptions: ['15', '30', '50'],
        showSizeChanger: true,
        total: 1,
        showTotal: (total) => `共 ${total} 条数据`,
        pageSize: 15,
        current: 1
      },
      pagination2: {
        pageSizeOptions: ['15'],
        showSizeChanger: false,
        total: 1,
        showTotal: (total) => `共 ${total} 条数据`,
        pageSize: 15
      },
      columns: [
        {
          title: 'ID',
          dataIndex: '_id'
        },
        {
          title: '标题',
          dataIndex: 'title'
        },
        {
          title: '域名',
          dataIndex: 'domain'
        },
        {
          title: 'IP',
          dataIndex: 'ip'
        },
        {
          title: '证书有效期',
          width: '220px',
          slots: { customRender: 'domain_expire' }
        },
        {
          title: '证书状态',
          slots: { customRender: 'is_expire' }
        },
        {
          title: '监控状态',
          dataIndex: 'status',
          slots: { customRender: 'status' }
        },
        {
          title: '上次检测时间',
          dataIndex: 'check_time'
        },
        {
          title: '添加时间',
          dataIndex: 'create_time'
        },
        {
          title: '操作',
          width: '270px',
          slots: { customRender: 'action' }
        }
      ],
      columns2: [
        {
          title: 'ID',
          dataIndex: '_id'
        },
        {
          title: '执行状态',
          dataIndex: 'status',
          slots: { customRender: 'status' }
        },
        {
          title: '监测时间',
          dataIndex: 'create_time'
        }
      ]
    })
    onMounted(() => {
      getDataList()
      getServerDataList()
    })
    function getServerDataList() {
      getPushServerList({}).then((res) => {
        state.allPush = res
      })
    }
    function deleteSelect() {
      Modal.confirm({
        title: '确认批量删除所选内容?',
        okType: 'danger',
        okText: '确认删除',
        onOk() {
          delServerBatch({ ids: state.selectedRowKeys })
            .then((res) => {
              if (res.code === 200) {
                state.loading = true
                reloadList()
                requestSuccess(res)
              } else {
                requestFailed(res)
              }
            })
            .finally(() => {
              state.selectedRowKeys = []
            })
        }
      })
    }
    const onSelectChange = (selectedRowKeys) => {
      state.selectedKeysPage[state.listQuery.pageNo] = selectedRowKeys
      let nowList: any[] = []
      for (const key in state.selectedKeysPage) {
        nowList = nowList.concat(state.selectedKeysPage[key])
      }
      const uniqueList = [...new Set(nowList)]
      state.selectedRowKeys = uniqueList
    }
    function handleTableChange(e) {
      state.loading = true
      state.pagination.pageSize = e.pageSize
      state.listQuery.pageSize = e.pageSize
      state.listQuery.pageNo = e.current
      state.pagination.current = e.current
      getDataList()
    }
    function resetSecret() {
      FormState.server_secret = randomString(64)
    }

    const FormState = reactive<any>({
      _id: '',
      title: '',
      aliyun_is_internal_upload_bool: '',
      aliyun_is_define_url_bool: '',
      aliyun_region: '',
      server_secret: '',
      aliyun_web_url: '',
      aliyun_bucket: '',
      aliyun_key_secret: '',
      aliyun_key_id: '',
      status: 1
    })
    const FormRule = {
      title: [{ required: true, message: '请输入标题', trigger: ['blur', 'change'] }],
      status: [{ required: true, message: '请输选择配置状态', trigger: ['blur', 'change'] }]
    }

    function reloadList() {
      state.loading = true
      state.listQuery.pageNo = 1
      state.pagination.current = 1
      getDataList()
    }

    function searchSubmit() {
      state.loading = true
      state.listQuery.pageNo = 1
      state.pagination.current = 1
      getDataList()
    }
    function handleTableChange2(e) {
      state.loading2 = true
      state.pagination2.pageSize = e.pageSize
      state.listQuery2.pageSize = e.pageSize
      state.listQuery2.pageNo = e.current
      ssl_monitor_log(state.single)
    }
    function ssl_monitor_log(item) {
      state.single = item
      state.listQuery2.ml_id = item._id
      state.logVisible = true
      state.loading2 = true
      getLog(state.listQuery2).then((res) => {
        state.loading2 = false
        state.dataListLog = res
        state.pagination2.total = res.totalCount
      })
    }
    function ssl_monitor_view(item) {
      if (item.start_date == undefined || item.start_date.length < 5) {
        message.error('暂无证书信息')
        return false
      }
      state.single = item
      state.viewVisible = true
    }
    function ssl_monitor_copy(itemData) {
      for (let item in FormState) {
        FormState[item] = ''
      }
      state.drawerTitle = '复制监控配置'
      for (let item in itemData) {
        if (item != '_id' && item != 'server_secret') {
          let copyTips = item == 'title' ? ' - 复制' : ''
          FormState[item] = itemData[item] + copyTips
        }
      }
      state.drawerShow = true
    }

    function getDataList() {
      getSSLList(state.listQuery).then((res) => {
        state.loading = false
        state.dataList = res
        state.pagination.total = res.totalCount
      })
    }
    function ssl_monitor_edit(res) {
      state.drawerTitle = '编辑监控配置'
      for (let item in FormState) {
        FormState[item] = ''
      }
      for (let item in res) {
        FormState[item] = res[item]
      }
      state.drawerShow = true
    }
    function addNewData() {
      for (let item in FormState) {
        FormState[item] = ''
      }
      state.drawerTitle = '新增监控配置'
      state.drawerShow = true
    }
    function ssl_monitor_delete(data) {
      Modal.confirm({
        title: '确认永久删除本配置?',
        content: '【' + data._id + '】',
        okType: 'danger',
        okText: '确认删除',
        onOk() {
          delServerItem({ id: data._id }).then((res) => {
            if (res.code === 200) {
              state.loading = true
              getDataList()
              requestSuccess(res)
            } else {
              requestFailed(res)
            }
          })
        }
      })
    }
    const addServer = () => {
      formRef.value
        .validate()
        .then(() => {
          editSslInfo(FormState).then((res) => {
            if (res.code === 200) {
              requestSuccess(res)
              formRef.value.resetFields()
              state.loading = true
              state.drawerShow = false
              reloadList()
            } else {
              requestFailed(res)
            }
          })
        })
        .catch(() => {
          return false
        })
    }
    return {
      ...toRefs(state),
      handleTableChange,
      handleTableChange2,
      reloadList,
      resetSecret,
      searchSubmit,
      ssl_monitor_delete,
      formRef,
      addServer,
      ssl_monitor_view,
      ssl_monitor_log,
      FormState,
      FormRule,
      addNewData,
      deleteSelect,
      onSelectChange,
      router,
      inArray,
      ssl_monitor_edit,
      ssl_monitor_copy,
      getDataList
    }
  }
})
</script>

<style scoped></style>
